备用返回通道
转到题目
思路1:二分
首先我们先用数学公式表述关系 \(B = \lfloor A/V \rfloor \tag{1}\) \(A = B*V + k (0<=k < V) \tag{2}\) \(根据(2)发现为线性函数,具有全局单调性 \Longrightarrow 二分答案\\ 根据(1)发现V 越大 B越大 \\ \Longrightarrow MIN根据每条记录找f(V) ==B的最小V \Longrightarrow收缩左边界 \\ 同理 \Longrightarrow MAX找每条记录f(V) ==B的最大V \Longrightarrow收缩右边界\)
#include<bits/stdc++.h>
using namespace std;
int A,B;
bool check1(int V)//V没到最小时
{
return B >= A/V;
}
bool check2(int V)//V没到最大时
{
return B<=A/V;
}
int mi= 0;
int ma= 1e9;
int l,r;
int main(){
int T;
cin>>T;
while(T--){
cin>>A>>B;
l = mi;
r = ma;
while(l<r){
int mid = (l+r)>>1;
if(check1(mid))r =mid;
else l = mid+1;
}
mi = max(mi,r);
l = mi;
r = ma;
while(l<r){
int mid =(l+r+1)>>1;
if(check2(mid))l = mid;
else r = mid-1;
}
ma = min(ma,l);
}
cout<<mi<<" "<<ma<<endl;
return 0;
}
思路2:数学推导
#include<bits/stdc++.h>
using namespace std;
/*
X: V O/X
每一条记录要保证
A = B*V +k (0<=k<V)
mi: V= (A-k)/B <=> V = (A-V+1)/B => V = vB = A -v+1 => V(B+1) =A+1 => V =(A+1)/(B+1)
向上取整=>保证合法 V = (A+B+1)/(B+1)
ma = V = A/B
向下取整保证合法 => V =A/B (没变)
B = floor(A/V) ==> V:[(A+B+1)/(B+1),A/B]
维护交集
*/
#define int long long
const int INF=0x3f3f3f3f3f3f3f3f;
#define inf INF
signed main(){
int mi = -inf;
int ma = inf;
int T ;
cin>>T;
int l,r;
int A,B;
while(T--){
cin>>A>>B;
l = (A+B+1)/(B+1);
r =A/B;
mi = max(l,mi);
ma = min(r,ma);
}
cout<<mi<<" "<<ma<<endl;
return 0;
}